using System;
using System.Collections.Generic;

namespace OffsetPath
{

    public static class OffsetPathMainClass
    {
        public static ClassN Elaborate(ClassAb A_0)
        {
            return new ClassN(new List<PuntoDueD> { new PuntoDueD(A_0.GetEndPnt()), new PuntoDueD(A_0.o(), A_0.f()), new PuntoDueD(A_0.GetStartPoint()), new PuntoDueD(A_0.e(), A_0.k()) }, false);
        }

        public static bool Elaborate(ClassC A_0, double offsetDistance, Dictionary<ForseLineaClassA, IList<ClassN>> A_2)
        {
            return Elaborate(A_0, offsetDistance, (double)0.0, A_2);
        }

        public static bool Elaborate(ClassC A_0, double offsetDistance, ContenitoreLivello A_2)
        {
            return Elaborate(A_0, offsetDistance, (double)0.0, A_2);
        }

        public static bool Elaborate(ClassN A_0, double offsetDistance, ContenitoreLivello A_2)
        {
            return Elaborate(A_0, offsetDistance, (double)0.0, A_2);
        }

        public static bool Elaborate(ClassN A_0, double offsetDistance, Dictionary<ForseLineaClassA, IList<ClassN>> A_2)
        {
            return Elaborate(A_0, offsetDistance, (double)0.0, A_2);
        }

        public static ClassAb Elaborate(ClassN A_0, double offsetDistance, double A_2)
        {
            ClassW.AggiustaAngolo(ref A_2);
            ClassAb classAb = new ClassAb();
            A_0.f(classAb);
            double num = offsetDistance;
            num /= Math.Sin(A_2 / 2.0);
            classAb.h((double)(num * 5.0));
            return classAb;
        }

        private static void Elaborate(ContenitoreLivello A_0, PolygonalShape A_1, bool A_2, bool A_3)
        {
            List<PolygonalShape> list = new List<PolygonalShape>();
            for (int i = A_0.Count - 1; i >= 0; i--)
            {
                list.Clear();
                ClassAg classAg = new ClassAg
                {
                    c = ClassAg.EnumA.c
                };
                A_0[i].MethodA1(A_1, list, A_2, A_3, classAg);
                if (list.Count > 0)
                {
                    A_0.RemoveAt(i);
                    A_0.InsertRange(i, list);
                    return;
                }
            }
            A_0.Add(A_1);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="A_0">ha a che fare con contenuto</param>
        /// <param name="offsetDistance">offset</param>
        /// <param name="A_2">ha a che fare con angolo..</param>
        /// <param name="A_3"></param>
        /// <returns></returns>
        public static bool Elaborate(ClassC A_0, double offsetDistance, double A_2, ContenitoreLivello A_3)
        {
            if ((A_0 == null) || (A_3 == null))
            {
                throw new ArgumentNullException();
            }
            if (offsetDistance <= 0.0)
            {
                // inner border 
                return ClassW.MethodA(A_0, Math.Abs(offsetDistance), A_2, false, A_3);
            }
            if (!Elaborate(new ClassN(A_0.a()), offsetDistance, A_2, A_3))
            {
                return false;
            }
            for (int i = 0; i < A_0.holesCount(); i++)
            {
                Elaborate(A_0.b(i), -offsetDistance, A_2, A_3);
            }
            return true;
        }

        public static bool Elaborate(ClassC profilo, double offsetDistance, double angleChamfer, Dictionary<ForseLineaClassA, IList<ClassN>> dictionaryRslt)
        {
            if ((profilo == null) || (dictionaryRslt == null))
            {
                throw new ArgumentNullException();
            }
            if (offsetDistance <= 0.0)
            {
                return ClassW.ElaborateBrokenBorder(profilo, Math.Abs(offsetDistance), angleChamfer, false, dictionaryRslt);
            }
            if (!Elaborate(new ClassN(profilo.a()), offsetDistance, angleChamfer, dictionaryRslt))
            {
                return false;
            }
            for (int i = 0; i < profilo.holesCount(); i++)
            {
                Elaborate(profilo.b(i), -offsetDistance, angleChamfer, dictionaryRslt);
            }
            return true;
        }

        public static bool Elaborate(ClassC A_0, double offsetDistance, int numberOffset, IList<ContenitoreLivello> A_3)
        {
            return Elaborate(A_0, offsetDistance, numberOffset, (double)0.0, A_3);
        }

        public static bool Elaborate(ClassN A_0, double offsetDistance, double A_2, ContenitoreLivello A_3)
        {
            if ((A_0 == null) || (A_3 == null))
            {
                throw new ArgumentNullException();
            }
            if (offsetDistance < 0.0)
            {
                return ClassW.MethodA(A_0, Math.Abs(offsetDistance), A_2, A_3);
            }
            ClassC classC = b(A_0, offsetDistance, A_2);
            if (classC == null)
            {
                return false;
            }
            return ClassW.MethodA(classC, Math.Abs(offsetDistance), A_2, true, A_3);
        }

        public static bool Elaborate(ClassN A_0, double offsetDistance, double A_2, Dictionary<ForseLineaClassA, IList<ClassN>> A_3)
        {
            if ((A_0 == null) || (A_3 == null))
            {
                throw new ArgumentNullException();
            }
            if (offsetDistance < 0.0)
            {
                return ClassW.MethodA(A_0, Math.Abs(offsetDistance), A_2, A_3);
            }
            ClassC classC = b(A_0, offsetDistance, A_2);
            if (classC == null)
            {
                return false;
            }
            return ClassW.ElaborateBrokenBorder(classC, Math.Abs(offsetDistance), A_2, true, A_3);
        }

        public static bool Elaborate(ClassN A_0, double offsetDistance, int numberOffset, IList<ContenitoreLivello> A_3)
        {
            return Elaborate(A_0, offsetDistance, numberOffset, (double)0.0, A_3);
        }

        public static bool Elaborate(ClassC A_0, double offsetDistance, ContenitoreLivello A_2, Dictionary<ForseLineaClassA, IList<ClassN>> A_3, ContenitoreLivello A_4)
        {
            return Elaborate(A_0, offsetDistance, 0.0, A_2, A_3, A_4);
        }

        public static bool Elaborate(ClassC A_0, double offsetDistance, int numberOffset, double angleToChamfer, IList<ContenitoreLivello> resultPathContainer)
        {
            if ((A_0 == null) || (resultPathContainer == null))
            {
                throw new ArgumentNullException();
            }
            resultPathContainer.Clear();
            if (offsetDistance <= 0.0)
            {
                return ClassW.MethodA(A_0, Math.Abs(offsetDistance), numberOffset, angleToChamfer, resultPathContainer);
            }
            if (numberOffset <= 0)
            {
                numberOffset = 1;
            }
            if (!Elaborate(new ClassN(A_0.a()), offsetDistance, numberOffset, angleToChamfer, resultPathContainer))
            {
                return false;
            }
            List<List<ContenitoreLivello>> list = new List<List<ContenitoreLivello>>();
            for (int i = 0; i < A_0.holesCount(); i++)
            {
                List<ContenitoreLivello> list2 = new List<ContenitoreLivello>();
                Elaborate(A_0.b(i), -offsetDistance, numberOffset, angleToChamfer, list2);
                list.Add(list2);
            }
            for (int j = 0; j < resultPathContainer.Count; j++)
            {
                ContenitoreLivello contenitoreLivello = resultPathContainer[j];
                foreach (List<ContenitoreLivello> list3 in list)
                {
                    if (list3.Count > j)
                    {
                        ContenitoreLivello ah2 = list3[j];
                        foreach (PolygonalShape ai in ah2)
                        {
                            Elaborate(contenitoreLivello, ai, false, true);
                        }
                        continue;
                    }
                }
            }
            return true;
        }

        public static bool Elaborate(ClassN A_0, double offsetDistance, ContenitoreLivello A_2, Dictionary<ForseLineaClassA, IList<ClassN>> A_3, ContenitoreLivello A_4)
        {
            return Elaborate(A_0, offsetDistance, 0.0, A_2, A_3, A_4);
        }

        public static bool Elaborate(ClassN A_0, double offsetDistance, int numberOffset, double angleToChamfer, IList<ContenitoreLivello> resultPathContainer)
        {
            if ((A_0 == null) || (resultPathContainer == null))
            {
                throw new ArgumentNullException();
            }
            if (offsetDistance < 0.0)
            {
                return ClassW.MethodA(A_0, Math.Abs(offsetDistance), numberOffset, angleToChamfer, resultPathContainer);
            }
            ClassC classC = b(A_0, offsetDistance * numberOffset, angleToChamfer);
            if (classC == null)
            {
                return false;
            }
            List<ContenitoreLivello> list = new List<ContenitoreLivello>();
            if (!ClassW.MethodA(classC, Math.Abs(offsetDistance), numberOffset, angleToChamfer, list))
            {
                return false;
            }
            resultPathContainer.Clear();
            for (int i = 0; i < list.Count; i++)
            {
                ContenitoreLivello contenitoreLivello = list[i];
                ContenitoreLivello item = new ContenitoreLivello();
                foreach (PolygonalShape ai in contenitoreLivello)
                {
                    for (int j = 0; j < ai.holesCount(); j++)
                    {
                        ClassC c2 = new ClassC(new ClassC(ai.GetHolesProfileAt(j)));
                        item.Add(c2);
                    }
                }
                foreach (PolygonalShape ai2 in contenitoreLivello)
                {
                    if (ai2.holesCount() == 0)
                    {
                        foreach (ClassC c3 in item)
                        {
                            if (c3.MethodB1(ai2))
                            {
                                c3.b(new ClassN(ai2.GetExternPolygon()));
                                break;
                            }
                        }
                        continue;
                    }
                }
                resultPathContainer.Add(item);
            }
            return true;
        }

        public static bool Elaborate(ClassC A_0, double offsetDistance, double A_2, ContenitoreLivello A_3, Dictionary<ForseLineaClassA, IList<ClassN>> A_4, ContenitoreLivello A_5)
        {
            if ((A_0 == null) || (((A_3 == null) && (A_4 == null)) && (A_5 == null)))
            {
                throw new ArgumentNullException();
            }
            if (offsetDistance <= 0.0)
            {
                return ClassW.MethodA(A_0, Math.Abs(offsetDistance), A_2, false, A_3, A_4, A_5);
            }
            if (!Elaborate(new ClassN(A_0.a()), offsetDistance, A_2, A_3, A_4, A_5))
            {
                return false;
            }
            ContenitoreLivello contenitoreLivello = (A_3 != null) ? new ContenitoreLivello() : null;
            for (int i = 0; i < A_0.holesCount(); i++)
            {
                new List<ContenitoreLivello>();
                Elaborate(A_0.b(i), -offsetDistance, A_2, contenitoreLivello, A_4, A_5);
            }
            if (A_3 != null)
            {
                foreach (PolygonalShape ai in contenitoreLivello)
                {
                    Elaborate(A_3, ai, false, true);
                }
            }
            return true;
        }

        public static bool Elaborate(ClassN A_0, double offsetDistance, double A_2, ContenitoreLivello A_3, Dictionary<ForseLineaClassA, IList<ClassN>> A_4, ContenitoreLivello A_5)
        {
            if ((A_0 == null) || (((A_3 == null) && (A_4 == null)) && (A_5 == null)))
            {
                throw new ArgumentNullException();
            }
            if (offsetDistance < 0.0)
            {
                return ClassW.MethodA(A_0, Math.Abs(offsetDistance), A_2, A_3, A_4, A_5);
            }
            ClassC classC = b(A_0, offsetDistance, A_2);
            if (classC == null)
            {
                return false;
            }
            ContenitoreLivello contenitoreLivello = (A_3 != null) ? new ContenitoreLivello() : null;
            if (!ClassW.MethodA(classC, Math.Abs(offsetDistance), A_2, true, contenitoreLivello, A_4, A_5))
            {
                return false;
            }
            if (A_3 != null)
            {
                A_3.Clear();
                foreach (PolygonalShape ai in contenitoreLivello)
                {
                    for (int i = 0; i < ai.holesCount(); i++)
                    {
                        ClassC item = new ClassC(new ClassC(ai.GetHolesProfileAt(i)));
                        A_3.Add(item);
                    }
                }
                foreach (PolygonalShape ai2 in contenitoreLivello)
                {
                    if (ai2.holesCount() == 0)
                    {
                        foreach (ClassC c3 in A_3)
                        {
                            if (c3.MethodB1(ai2))
                            {
                                c3.b(new ClassN(ai2.GetExternPolygon()));
                                break;
                            }
                        }
                        continue;
                    }
                }
            }
            return true;
        }

        public static ClassC b(ClassN A_0, double A_1, double A_2)
        {
            ClassAb classAb = Elaborate(A_0, A_1, A_2);
            if ((double.IsNaN(classAb.l()) || double.IsInfinity(classAb.l())) || (double.IsNaN(classAb.n()) || double.IsInfinity(classAb.n())))
            {
                return null;
            }
            ClassC classC = new ClassC(Elaborate(classAb));
            classC.b(A_0);
            return classC;
        }
    }

}